package com.wontube.smr.bo.sites.fs;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
import java.util.UUID;

import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.SqlSession;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import com.wontube.client.extension.utils.StringUtils;
import com.wontube.client.extension.utils.net.URLUtils;
import com.wontube.core.dao.mybatis.QueryExample;
import com.wontube.smr.bo.sites.fs.conf.FourShared;
import com.wontube.smr.client.model.po.TopMusic;
import com.wontube.smr.dao.mapper.TopMusicMapper;
import com.wontube.smr.pub.DefaultDBHelper;


/**
 * @author yuechao
 * 
 */
public final class TopMusicObtainBO {
	public static HashMap<String, List<TopMusic>> getTopMusic() {
		HashMap<String, List<TopMusic>> map = new HashMap<String, List<TopMusic>>();
		SqlSession session = DefaultDBHelper.getSqlSession(true);
		try {
			TopMusicMapper mapper = session.getMapper(TopMusicMapper.class);
			String categary = "last_fm";
			map.put(categary, TopMusicObtainBO.selectCategary(mapper, categary));
			categary = "billboard";
			map.put(categary, TopMusicObtainBO.selectCategary(mapper, categary));
			categary = "uk";
			map.put(categary, TopMusicObtainBO.selectCategary(mapper, categary));
			categary = "itunes";
			map.put(categary, TopMusicObtainBO.selectCategary(mapper, categary));
		} finally {
			session.close();
		}

		return map;
	}
	
	public static List<TopMusic> getCategary(String categary) {
		SqlSession session = DefaultDBHelper.getSqlSession(true);
		try {
			TopMusicMapper mapper = session.getMapper(TopMusicMapper.class);
			return TopMusicObtainBO.selectCategary(mapper, categary);
		} finally {
			session.close();
		}
	}

	public static HashMap<String, ArrayList<TopMusic>> obtainFromWeb() throws IOException {
		HashMap<String, ArrayList<TopMusic>> map = new HashMap<String, ArrayList<TopMusic>>();
		// billboard
		ArrayList<TopMusic> list = obtainFromQQ("http://y.qq.com/y/static/toplist/index/global_7.html");
		map.put("billboard", list);

		// iTunes
		list = obtainFromQQ("http://y.qq.com/y/static/toplist/index/global_12.html?pgv_ref=qqmusic.y.toplist.global_12");
		map.put("itunes", list);
		
		// UK
		list = obtainFromQQ("http://y.qq.com/y/static/toplist/index/global_6.html?pgv_ref=qqmusic.y.toplist.global_6");
		map.put("uk", list);
		
		// last.fm
		list = obtainFromLastfm();
		map.put("last_fm", list);
		
		// 注意，分析完成再保存到数据库，防止长期锁定
		SqlSession session = DefaultDBHelper.getSqlSession(false);
		try {
			TopMusicMapper mapper = session.getMapper(TopMusicMapper.class);
			int count = 0;
			for (Entry<String, ArrayList<TopMusic>> entry : map.entrySet()) {
				count++;
				for (TopMusic music : entry.getValue()) {
					
					QueryExample ex = new QueryExample();
					ex.or().addCriterion("categary=", entry.getKey())
						.addCriterion("name=", music.getName())
						.addCriterion("singer=", music.getSinger());
					List<TopMusic> voList = mapper.selectByExample(ex);
					TopMusic vo = new TopMusic();
					if (voList.size() > 0) { // 已经存在
						vo = voList.get(0);
						vo.setIndex(count);
						// 更新时间戳
						vo.setVersion(Calendar.getInstance().getTime());
						mapper.updateByPrimaryKey(vo);
					} else {
						vo.setCategary(entry.getKey());
						vo.setId(UUID.randomUUID().toString());
						vo.setName(music.getName());
						vo.setSinger(music.getSinger());
						vo.setIndex(count);
						mapper.insert(vo);
					}
				}
			}
			session.commit();
		} finally {
			session.close();
		}
		
		return map;
	}
	
	public static ArrayList<TopMusic> obtainFromLastfm() throws IOException {
		ArrayList<TopMusic> listResult = new ArrayList<TopMusic>();
		String url = "http://cn.last.fm/charts/tracks/top";
		URL uri = new URL(url);
		Document doc = Jsoup.parse(uri, 20000);
		Elements elements = doc.select(".rankedChart > ol > li");
		
		if (elements.size() < 1) {
			return listResult;
		}
		
		for (int i = 0; i < elements.size() && listResult.size() < 10; i++) {
			Element element = elements.get(i);
			String text = element.select(".rankItem-wrap > div > a .rankItem-title").eq(0).text();
			String[] args = text.split("[–]");
			if (args.length < 2) {
				continue;
			}
			String name = args[1].trim();
			name = name.replaceAll("[(.)']", "");
			if (!isExist(name)) {
				continue;
			}
			
			String singer = args[0].trim();
			TopMusic music = new TopMusic();
			music.setName(name);
			music.setSinger(singer);
			listResult.add(music);
		}
		
		return listResult;
	}
	
	public static ArrayList<TopMusic> obtainFromQQ(String url) throws IOException {
		ArrayList<TopMusic> listResult = new ArrayList<TopMusic>();
		URL uri = new URL(url);
		Document doc = Jsoup.parse(uri, 20000);
		Elements elements = doc.select("#divsonglist > li");

		for (int i = 0; i < elements.size() && listResult.size() < 10; i++) {
			Element element = elements.get(i);
			String text = element.select(".music_name > span.txt > a").text();
			text = text.replaceAll("[(.)']", "");
			if (StringUtils.isNullOrEmpty(text) || !isExist(text)) {
				continue;
			}

			TopMusic music = new TopMusic();
			music.setName(text);
			text = element.select(".singer_name > span.txt > a").text();
			music.setSinger(text);

			listResult.add(music);
		}
		
		return listResult;
	}

	/**luobiao write */
	private static String apiUrl = "http://search.4shared.com/network/searchXml.jsp?searchCategory=music/audio&searchExtention=mp3&sortType=5&sortOrder=1&searchmode=3";
	public static boolean isExist(String musicName){
		if (!FourShared.fs.isUseMp3Skull() || isNotAllEnglish(musicName)) {
			//到4share中查询
			String q = URLUtils.encodeURIComponent(musicName);
			int start = 0;
			String urlStr = apiUrl + "&q=" + q + "&start=" + start;
			URL url = null;
			int mp3Count = 0;
			try {
				url = new URL(urlStr);
				mp3Count = new ObtainFSMp3CountByName().getMp3Count(url.openStream());
			} catch (Exception e) {
				e.printStackTrace();
			}
			if(mp3Count > 0){
				//System.out.println("4share中有此歌曲 " + mp3Count + " 首");
				return true;
			}
			//System.out.println("4share中没有此歌曲");
			return false;
		}
		//到MP3skull中查询
		while (musicName.contains("  ")) {
			musicName = musicName.replace("  ", " ");
		}
		musicName = musicName.replace(' ', '_').replace(".", "");
		String url = "http://mp3skull.com/mp3/" + musicName + ".html";
		URL uri = null;
		Document doc = null;
		try {
			uri = new URL(url);
			doc = Jsoup.parse(uri, 20000);
		} catch (Exception e) {
			e.printStackTrace();
		}
		Elements el = doc.select("div.show1");
		if(el.size() > 0){
			//System.out.println("mp3Skull中有此歌曲。");
			return true;
		}else{
			//System.out.println("mp3Skull中无此歌曲。");
			return false;
		}
	}
	private static boolean isNotAllEnglish(String s) {
		if (s == null) {
			return false;
		}
		return s.getBytes().length != s.length();
	}
	/** luobiao write end*/
	
	/*private static boolean isExistOld(String musicName) {
		try {
			AudioFiles audioFiles = Mp3SearchBO.search(musicName, 1);
			return audioFiles.getFiles().size() > 0;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}*/
	
	private static List<TopMusic> selectCategary(TopMusicMapper mapper, String categary) {
		QueryExample ex = new QueryExample();
		ex.or().addCriterion("categary=", categary);
		ex.setOrderByClause("index asc, version desc");
		RowBounds rowBounds = new RowBounds(0, 10);

		List<TopMusic> list = mapper.selectByExample(ex, rowBounds);
		return list;
	}
}
